package com.wlyuan.open.domain.client;

import com.wlyuan.core.domain.valueobj.Mobile;
import com.wlyuan.core.domain.valueobj.TenantId;
import com.wlyuan.core.domain.valueobj.UserId;
import com.wlyuan.core.marker.NamedStatus;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author yuanzheng
 */
@Data
@RequiredArgsConstructor
public class OpenClient {
    private OpenClientId id;
    private String name;
    private String mobile;
    private final String appId;
    private final List<String> apiList;
    private String sourceRaw;
    private String appSecret;
    private TenantId tenantId;
    private UserId userId;
    private LocalDateTime createAt;
    private LocalDateTime updateAt;
    @ApiModelProperty("状态 0 禁用 1 启用")
    private NamedStatus status;
    @ApiModelProperty("更新人")
    private String updateBy;
    @ApiModelProperty("拒绝原因")
    private String reason;

    public OpenClient init(Mobile mobile) {
        changeMobile(mobile);
        this.createAt = LocalDateTime.now();
        this.updateAt = LocalDateTime.now();
        this.status = NamedStatus.AUDITING;
        this.reason = "";
        this.updateBy = "";
        return this;
    }

    public OpenClient bind(TenantId tenantId, UserId userId) {
        this.userId = userId;
        this.tenantId = tenantId;
        this.updateAt = LocalDateTime.now();
        return this;
    }

    public OpenClient bind(TenantId tenantId, UserId userId, String name) {
        this.userId = userId;
        this.tenantId = tenantId;
        this.updateAt = LocalDateTime.now();
        this.name = name;
        return this;
    }

    public OpenClient unbind() {
        this.userId = null;
        this.tenantId = null;
        this.name = null;
        this.updateAt = LocalDateTime.now();
        return this;
    }

    public OpenClient changeSecret(String appSecret, PasswordEncoder encoder) {
        this.appSecret = encoder.encode(appSecret);
        return this;
    }

    public OpenClient enable(String user) {
        this.status = NamedStatus.ENABLED;
        this.updateAt = LocalDateTime.now();
        this.updateBy = user;
        return this;
    }

    public OpenClient disable(String user) {
        this.status = NamedStatus.DISABLED;
        this.updateAt = LocalDateTime.now();
        this.updateBy = user;
        return this;
    }

    public OpenClient approved(String user) {
        this.status = NamedStatus.ENABLED;
        this.updateAt = LocalDateTime.now();
        this.updateBy = user;
        this.reason = "";
        return this;
    }

    public OpenClient rejected(String user, String reason) {
        this.status = NamedStatus.REJECTED;
        this.updateAt = LocalDateTime.now();
        this.updateBy = user;
        this.reason = reason;
        return this;
    }

    public OpenClient changeMobile(Mobile mobile) {
        this.mobile = mobile.getValue();
        return this;
    }

    public OpenClient changeRaw(String sourceRaw) {
        this.sourceRaw = sourceRaw;
        return this;
    }

    public boolean bind() {
        return this.tenantId != null && this.tenantId.getId() > 0;
    }

    public boolean hasEnable() {
        return NamedStatus.ENABLED.equals(this.status);
    }

    public boolean hasDisable() {
        return NamedStatus.DISABLED.equals(this.status);
    }

    public boolean hasReject() {
        return NamedStatus.REJECTED.equals(this.status);
    }

    public boolean hasAuditing() {
        return NamedStatus.AUDITING.equals(this.status);
    }
}
